home *** CD-ROM | disk | FTP | other *** search
/ Cracker's Matrix / Cracker's Matrix (nCite Software).iso / Examples / Data / ckSL_0016.txt < prev    next >
Text File  |  2003-01-06  |  13KB  |  267 lines

  1. DETTEN CRACKME #6
  2. *****************
  3.  
  4. Cracker:      figugegl
  5. Email:        figugegl_2000@yahoo.de
  6. Date:         20.10.2001
  7. Tools:        Softice, IDA
  8. Level 1-10:   5
  9.  
  10.  
  11.  
  12. A strange crackme with surprises! We see that the Register Button is greyed - we could easily patch this with a resource editor, but that's for newbies only (see info). Let's have a closer look at the imports: We see RegisterHotkey - interesting! We find this in the listing:
  13.  
  14. 004012C7 6A 51                 push 51h                         ; 'Q'
  15. 004012C9 6A 03                 push 3                           ; CTRL-ALT
  16. 004012CB 68 81 00 00 00        push 81h
  17. 004012D0 53                    push ebx
  18. 004012D1 E8 F4 8B 00 00        call j_RegisterHotKey
  19. 004012D6 85 C0                 test eax, eax
  20. 004012D8 0F 85 E3 00 00 00     jnz loc_4013C1
  21.  
  22. The API-Reference is very helpful in this case:
  23.  
  24. BOOL RegisterHotKey
  25. (
  26.     HWND hWnd,         // window to receive hot-key notification
  27.     int id,            // identifier of hot key
  28.     UINT fsModifiers,  // key-modifier flags: MOD_ALT, MOD_CONTROL, MOD_SHIFT
  29.     UINT vk            // virtual-key code
  30. );    
  31.  
  32. To get the values of the parameter fsModifiers we have a look at the file Winuser.h of our C-Compiler:
  33.  
  34.     #define MOD_ALT      1
  35.     #define MOD_CONTROL  2
  36.     #define MOD_SHIFT    4
  37.  
  38. The hotkey is "Ctrl-Alt-Q". To see what's happening, we set a bpx GetDlgItemTextA, fill in our name and serial and"Ctrl-Alt-Q":
  39.  
  40. 00401309 57                    push edi
  41. 0040130A 56                    push esi
  42. 0040130B 6A 65                 push 65h
  43. 0040130D 53                    push ebx
  44. 0040130E E8 A5 8B 00 00        call j_GetDlgItemTextA           ; si pops up here: get name
  45. 00401313 56                    push esi
  46. 00401314 E8 56 FE FF FF        call sub_40116F                  ; call 1
  47. 00401319 59                    pop ecx
  48. 0040131A 84 C0                 test al, al                      ; test flag
  49. 0040131C 0F 84 9F 00 00 00     jz  loc_4013C1                   ; bad cracker jump 1
  50. 00401322 6A 01                 push 1
  51. 00401324 68 C9 00 00 00        push 0C9h
  52. 00401329 53                    push ebx
  53. 0040132A E8 7D 8B 00 00        call j_GetDlgItem
  54. 0040132F 50                    push eax
  55. 00401330 E8 65 8B 00 00        call j_EnableWindow              ; enable register button
  56. 00401335 56                    push esi
  57. 00401336 E8 CD FD FF FF        call sub_401108                  ; call 2
  58. 0040133B 59                    pop ecx
  59. 0040133C E9 80 00 00 00        jmp loc_4013C1
  60.  
  61. It gets our name and then executes call 1:
  62.  
  63. 0040116F 55                    push ebp
  64. 00401170 8B EC                 mov ebp, esp
  65. 00401172 53                    push ebx
  66. 00401173 8B 55 08              mov edx, [ebp+arg_0]             ; pointer to name (n)
  67. 00401176 33 C0                 xor eax, eax
  68. 00401178 33 C9                 xor ecx, ecx
  69. 0040117A EB 0E                 jmp short loc_40118A
  70. 0040117C 0F BE 1C 02           movsx ebx, byte ptr [edx+eax]    ; loop start
  71. 00401180 D1 FB                 sar ebx, 1                       ; n[i] >> 1
  72. 00401182 79 03                 jns short loc_401187             ; jmp when positive
  73. 00401184 83 D3 00              adc ebx, 0                       ; add with carry (when negative)
  74. 00401187 03 CB                 add ecx, ebx                     ; add (when positive)
  75. 00401189 40                    inc eax
  76. 0040118A 80 3C 02 00           cmp byte ptr [edx+eax], 0
  77. 0040118E 75 EC                 jnz short loc_40117C             ; loop end
  78. 00401190 3B 0D E8 A0 40 00     cmp ecx, dword_40A0E8            ; sum == 20Ah ?
  79. 00401196 75 05                 jnz short loc_40119D
  80. 00401198 B0 01                 mov al, 1                        ; yes, set flag
  81. 0040119A 5B                    pop ebx
  82. 0040119B 5D                    pop ebp
  83. 0040119C C3                    retn
  84.  
  85. All characters of our name are shifted to the right and added. Note that they are signed characters. The sum must be 20Ah. Is this the case it enables the register button and executes the second call:
  86.  
  87. 00401108 55                    push ebp
  88. 00401109 8B EC                 mov ebp, esp
  89. 0040110B 83 C4 F8              add esp, 0FFFFFFF8h
  90. 0040110E 53                    push ebx
  91. 0040110F 57                    push edi
  92. 00401110 C7 45 FC 37 12 40+    mov [ebp+var_4], offset loc_401237
  93. 00401117 8D 45 F8              lea eax, [ebp+var_8]
  94. 0040111A 50                    push eax
  95. 0040111B 6A 04                 push 4
  96. 0040111D 6A 33                 push 33h
  97. 0040111F FF 75 FC              push [ebp+var_4]
  98. 00401122 E8 5B 8D 00 00        call j_VirtualProtect
  99. 00401127 52                    push edx
  100. 00401128 57                    push edi
  101. 00401129 50                    push eax
  102. 0040112A 8B 7D FC              mov edi, [ebp+var_4]             ; pointer to addresse 401237 (c)
  103. 0040112D C6 07 90              mov byte ptr [edi], 90h          ; [401237] = 90h (nop)
  104. 00401130 47                    inc edi
  105. 00401131 C6 07 90              mov byte ptr [edi], 90h          ; [401238] = 90h (nop)
  106. 00401134 47                    inc edi
  107. 00401135 8B 55 08              mov edx, [ebp+arg_0]             ; pointer to name (n)
  108. 00401138 BB 33 00 00 00        mov ebx, 33h                     ; loop counter
  109. 0040113D 8A 27                 mov ah, [edi]                    ; loop start
  110. 0040113F 8A 02                 mov al, [edx]                    ; n[i]
  111. 00401141 32 E0                 xor ah, al                       ; c[i] xor n[i]
  112. 00401143 88 27                 mov [edi], ah                    ; c[i] = c[i] xor n[i]
  113. 00401145 47                    inc edi
  114. 00401146 42                    inc edx
  115. 00401147 85 DB                 test ebx, ebx
  116. 00401149 74 0B                 jz  short loc_401156
  117. 0040114B 4B                    dec ebx
  118. 0040114C 80 3A 00              cmp byte ptr [edx], 0
  119. 0040114F 75 EC                 jnz short loc_40113D             ; loop end
  120. 00401151 8B 55 08              mov edx, [ebp+arg_0]
  121. 00401154 EB E7                 jmp short loc_40113D
  122. 00401156 58                    pop eax
  123. 00401157 5F                    pop edi
  124. 00401158 5A                    pop edx
  125. 00401159 8D 55 F8              lea edx, [ebp+var_8]
  126. 0040115C 52                    push edx
  127. 0040115D 6A 10                 push 10h
  128. 0040115F 6A 33                 push 33h
  129. 00401161 FF 75 FC              push [ebp+var_4]
  130. 00401164 E8 19 8D 00 00        call j_VirtualProtect
  131. 00401169 5F                    pop edi
  132. 0040116A 5B                    pop ebx
  133. 0040116B 59                    pop ecx
  134. 0040116C 59                    pop ecx
  135. 0040116D 5D                    pop ebp
  136. 0040116E C3                    retn
  137.  
  138. He, what's this! The crackme decrypts part of itself at address 401237. It xors our name with the code there - seems that we have to type in a unlock code first and then press Ctrl-Alt-Q to enable our button and to decrypt a part of the code.
  139.  
  140. Let's have a look at the serial algo first. In the listing we search for another occurence of GetDlgItemTextA, there are only two:
  141.  
  142. 004011DD 55                    push ebp
  143. 004011DE 8B EC                 mov ebp, esp
  144. 004011E0 51                    push ecx
  145. 004011E1 53                    push ebx
  146. 004011E2 56                    push esi
  147. 004011E3 57                    push edi
  148. 004011E4 33 DB                 xor ebx, ebx
  149. 004011E6 C7 45 FC B9 10 0F+    mov dword ptr [ebp-4], 0F10B9h
  150. 004011ED BF 3B 12 40 00        mov edi, offset loc_40123B
  151. 004011F2 80 3F 8A              cmp byte ptr [edi], 8Ah          ; [40123B] == 8Ah ?
  152. 004011F5 0F 85 7E 00 00 00     jnz loc_401279
  153. 004011FB 6A 65                 push 65h
  154. 004011FD FF 75 08              push dword ptr [ebp+8]
  155. 00401200 E8 A7 8C 00 00        call j_GetDlgItem
  156. 00401205 50                    push eax
  157. 00401206 E8 B3 8C 00 00        call j_GetWindowTextLengthA
  158. 0040120B 8B F8                 mov edi, eax
  159. 0040120D 8D 47 01              lea eax, [edi+1]
  160. 00401210 50                    push eax
  161. 00401211 6A 40                 push 40h
  162. 00401213 E8 F8 8B 00 00        call j_GlobalAlloc
  163. 00401218 8B F0                 mov esi, eax
  164. 0040121A 47                    inc edi
  165. 0040121B 57                    push edi
  166. 0040121C 56                    push esi
  167. 0040121D 6A 65                 push 65h
  168. 0040121F FF 75 08              push dword ptr [ebp+8]
  169. 00401222 E8 91 8C 00 00        call j_GetDlgItemTextA           ; get name
  170. 00401227 6A 00                 push 0
  171. 00401229 6A 00                 push 0
  172. 0040122B 6A 66                 push 66h
  173. 0040122D FF 75 08              push dword ptr [ebp+8]
  174. 00401230 E8 7D 8C 00 00        call j_GetDlgItemInt             ; get serial
  175. 00401235 8B F8                 mov edi, eax
  176. 00401237 EB 3D                 jmp short near ptr loc_401272+4  ; will be nop nop (see above)
  177. 00401239 A4                    movsb                            ; this code is being decrypted
  178. 0040123A 5A                    pop edx
  179. 0040123B EF                    out dx, eax
  180. 0040123C 6A 3E                 push 3Eh
  181. 0040123E 67 34 3E              db      67h
  182. 0040123E                       xor al, 3Eh
  183. 00401241 45                    inc ebp
  184. 00401242 7A DA                 jp  short near ptr loc_40121D+1
  185. 00401244 B5 4E                 mov ch, 4Eh
  186. 00401246 25 99 EE 5C 4B        and eax, 4B5CEE99h
  187. 0040124B 71 20                 jno short near ptr loc_401269+4
  188. 0040124D 30 7B 6B              xor [ebx+6Bh], bh
  189. 00401250 DB 03                 fild dword ptr [ebx]
  190. 00401252 6E                    outsb
  191. 00401253 64 E5 65              segfs
  192. 00401253                       in  eax, 65h
  193. 00401256 A9 E9 D7 BD FC        test eax, 0FCBDD7E9h
  194. 0040125B 21 99 24 3D 99 21     and [ecx+21993D24h], ebx
  195. 00401261 A9 18 8C 63 C4        test eax, 0C4638C18h
  196. 00401266 49                    dec ecx
  197. 00401267 7A 65                 jp  short near ptr loc_4012CB+3
  198. 00401269 3A A0 66 91 3B 7D     cmp ah, [eax+7D3B9166h]
  199. 0040126F FC                    cld
  200. 00401270 75 07                 jnz short loc_401279
  201. 00401272 C6 05 EC A0 40 00+    mov byte_40A0EC, 1               ; set flag
  202. 00401279 5F                    pop edi
  203. 0040127A 5E                    pop esi
  204. 0040127B 5B                    pop ebx
  205. 0040127C 59                    pop ecx
  206. 0040127D 5D                    pop ebp
  207. 0040127E C3                    retn
  208.  
  209. The byte at address 40123B must be 8Ah. After that check the crackme reads our name and serial and executes the decrypted code. At address 401272 it sets a flag. The flag is being tested in the maincode after the return:
  210.  
  211. 0040135D C6 05 EC A0 40 00+    mov byte_40A0EC, 0               ; clear flag
  212. 00401364 56                    push esi
  213. 00401365 53                    push ebx
  214. 00401366 E8 72 FE FF FF        call loc_4011DD                  ; see call above
  215. 0040136B 83 C4 08              add esp, 8
  216. 0040136E 0F BE 15 EC A0 40+    movsx edx, byte_40A0EC           ; flag
  217. 00401375 4A                    dec edx
  218. 00401376 75 1C                 jnz short loc_401394             ; flag - 1 == 0 ?
  219. 00401378 BE EE A0 40 00        mov esi, offset aErrorlevel1     ; "Errorlevel1!"
  220. 0040137D 56                    push esi
  221. 0040137E E8 1F FE FF FF        call sub_4011A2                  ; string "Errorlevel1!" --> "Registered !"
  222. 00401383 59                    pop ecx
  223. 00401384 6A 00                 push 0
  224. 00401386 68 FB A0 40 00        push offset aMessage ; "Message"
  225. 0040138B 56                    push esi
  226. 0040138C 53                    push ebx
  227. 0040138D E8 32 8B 00 00        call j_MessageBoxA               ; BINGO
  228. 00401392 EB 2D                 jmp short loc_4013C1
  229.  
  230. What we know about the unlock code (u):
  231.  
  232. * sum (n[i] sar 1) = 20Ah
  233. * u[2] xor EFh = 8Ah   -->  u[2] = 65h
  234. * to set the flag we have to jump to address 401272
  235.  
  236. The opcode reference tells us, that "mov r8, r8" begins with 8Ah. That's what we need for the third byte. We could do the following:
  237.  
  238. 401239: A4 5A  --> 8A C3  mov al, bl   ; dummy code (same as below to make things easier)
  239. 40123B: EF 6A  --> 8A C3  mov al, bl   ; dummy code, byte [40123B] must be 8Ah!
  240. 40123D: 3E 67  --> EB 33  jmp 401272   ; jump to location where flag is being set
  241.  
  242. Now we can calculate the first part of our unlock code:
  243.  
  244. u[0]: A4 xor 8A = 2E
  245. u[1]: 5A xor C3 = 99
  246. u[2]: EF xor 8A = 65
  247. u[3]: 6A xor C3 = A9
  248. u[4]: 3E xor EB = D5
  249. u[5]: 67 xor 33 = 54
  250.  
  251. When we trace in softice we see that this unlock code adds to zero. We have to add some more characters to get our sum of 20Ah. The decrypted code doesn't matter because of the jump. I played a bit with my calculator:
  252.  
  253. u[6]..u[23] = 3A
  254.  
  255.     Unlock:  .Öe⌐╒T::::::::::::::::::
  256.     *********************************
  257.  
  258. a) start crackme
  259. b) type in unlock Code
  260. c) press Ctrl-Alt-Q
  261. d) type in name and any serial
  262. e) press register button
  263. f) REGISTERED!
  264.  
  265. Strange things happen to our keyboard while playing with this crackme and my unlock code. Maybe my solution wasn't what detten had in mind - anyway, it works fine and you don't even need a keygen!
  266.  
  267. figugegl